本篇文章將撰寫一個應用程式,抓取【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 中的資料 Title、Links、PublishDate,經過資料整理與分析後顯示於 Windows Phone App 中。

本文刊載於
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
在這篇文章您可以學到:
取得【微軟最有價值專家 Microsoft MVP 台灣粉絲團】RSS 網址
連結至粉絲團網址 https://www.facebook.com/twmvp,隨意點選任意照片,取得 ID 為 215783948459346

RSS 網址為 https://www.facebook.com/feeds/page.php?format=atom10&id=上述步驟取得的 ID
組合後的網址 https://www.facebook.com/feeds/page.php?format=atom10&id=215783948459346
程式開發
新增專案,在此我使用樞紐分析應用程式,名稱為 MvpRssPhoneApp。

先開啟 ItemViewModel.cs

修改 ItemViewModel 屬性為 Title、Links、PublishDate
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace MvpRssPhoneApp.ViewModels
{
    public class ItemViewModel : INotifyPropertyChanged
    {
        private string _Title;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Title
        {
            get
            {
                return _Title;
            }
            set
            {
                if (value != _Title)
                {
                    _Title = value;
                    NotifyPropertyChanged("Title");
                }
            }
        }
        private string _Links;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string Links
        {
            get
            {
                return _Links;
            }
            set
            {
                if (value != _Links)
                {
                    _Links = value;
                    NotifyPropertyChanged("Links");
                }
            }
        }
        private string _PublishDate;
        /// <summary>
        /// 範例 ViewModel 屬性; 這個屬性是用在檢視中,以使用繫結來顯示其值。
        /// </summary>
        /// <returns></returns>
        public string PublishDate
        {
            get
            {
                return _PublishDate;
            }
            set
            {
                if (value != _PublishDate)
                {
                    _PublishDate = value;
                    NotifyPropertyChanged("PublishDate");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
開啟 MainPage.xaml 設計畫面

在 StackPanel 內的顯示內容有兩個 TextBlock。

<StackPanel Margin="0,0,0,17">
    <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
    <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
我們多加一個 TextBlock,分別 Binding 屬性 Title、Links、PublishDate
<StackPanel Margin="0,0,0,17">
    <TextBlock Text="{Binding Title}" TextWrapping="Wrap" Style="{StaticResource PhoneTextNormalStyle}"/>
    <TextBlock Text="{Binding Links}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
    <TextBlock Text="{Binding PublishDate}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextAccentStyle}"/>
</StackPanel>
我們要做的事情是下載 RSS 資料,分析與加入資料,開啟 MainViewModel.cs

在 LoadData() 的部分,我們先修改成
/// <summary>
/// 建立並加入一些 ItemViewModel 物件到 Items 集合。
/// </summary>
public void LoadData()
{
    // 範例資料; 以真實資料取代
    this.Items.Add(new ItemViewModel() { Title = "測試標題" , Links = "http://www.dotblogs.com.tw/chou", PublishDate = DateTime.Now.ToString() });
    this.IsDataLoaded = true;
}
執行看看,有資料了

接著,我們替換真實資料,修改 Load(),透過 WebClient 類別下載 RSS 資料。
/// <summary>
/// 建立並加入一些 ItemViewModel 物件到 Items 集合。
/// </summary>
public void LoadData()
{
    WebClient webClient = new WebClient();
    webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    webClient.DownloadStringAsync(new System.Uri("https://www.facebook.com/feeds/page.php?format=atom10&id=215783948459346"));
    this.IsDataLoaded = true;
}
當非同步資源下載完成時,觸發 webClient_DownloadStringCompleted 事件,在事件中,如果下載 RSS 資料完成,則做進一步處理 (叫用 ProcessRssData 傳入下載 RSS 資料),沒有下載完成則報錯。
private void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error != null)
    {
        Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            MessageBox.Show(e.Error.Message);
        });
    }
    else
    {
        ProcessRssData(e.Result);
    }
}
在 ProcessRssData 中,將下載後的 RSS 資料,處理後加入 Items 中。
在 .NET framework 想要處理 Atom 1.0 和 RSS 2.0 可以透過 SyndicationFeed 類別
SyndicationFeed 類別 : 代表最上層的摘要的物件,<feed> 在 Atom 1.0 和 <rss> 以 RSS 2.0。
想要使用該類別,必須先加入參考,位置在
c:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.ServiceModel.Syndication.dll

加入時可能有警告視窗,請按是

加入完成

撰寫 PrcoessRssData,將下載後的 RSS 資料,透過 SyndicationFeed 類別解析後,將 Tilte、Links、PublishDate 屬性的資料,加入 Items 中。
private void ProcessRssData(string RssData)
{
    StringReader stringReader = new StringReader(RssData);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    SyndicationFeed feed = SyndicationFeed.Load(xmlReader);
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        foreach (var item in feed.Items)
        {
            this.Items.Add(new ItemViewModel()
            {
                Title = HttpUtility.HtmlDecode(item.Title.Text),
                Links = item.Links.Count > 0 ? item.Links[0].Uri.ToString() : string.Empty,
                PublishDate = item.PublishDate.DateTime.ToString()
            }
        );
        }
    });
}
什麼時候會去呼叫 Model,開啟 MainPage.xaml.cs 程式碼,在 OnNavigatedTo 時,呼叫 Model 的 LoadData() 載入資料。

執行結果,Tilte 的資料看起來像是亂碼。

我們透過 HttpUtility.HtmlDecode 方法將已經為 HTTP 傳輸而進行 HTML 編碼的字串轉換為解碼的字串。
private void ProcessRssData(string RssData)
{
    StringReader stringReader = new StringReader(RssData);
    XmlReader xmlReader = XmlReader.Create(stringReader);
    SyndicationFeed feed = SyndicationFeed.Load(xmlReader);
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        foreach (var item in feed.Items)
        {
            this.Items.Add(new ItemViewModel()
            {
                Title = HttpUtility.HtmlDecode(item.Title.Text),
                Links = item.Links.Count > 0 ? item.Links[0].Uri.ToString() : string.Empty,
                PublishDate = item.PublishDate.DateTime.ToString()
            }
        );
        }
    });
}
重新執行,可顯示粉絲團上的資料。

其他相關資訊
<How to create a basic RSS reader for Windows Phone>
範例下載
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
在這裡貼文
被 dotblogs 擋外連圖片就算了
沒想到看原文
http://www.dotblogs.com.tw/chou/archive/2013/09/11/118178.aspx
圖片還是被擋掉
看不到圖片

神奇的是
在原文點圖片另開啟視窗時
是可以看到圖片的
